package com.xiaobao.campusLostFoundAfter.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.UUID;

@Component
public class FileStorageUtil {
    // 上传根目录
    @Value("${upload.path:D:/uploadsImages}")
    private String uploadRootPath;
    // 文件访问URL前缀
    @Value("${upload.url.prefix:http://172.20.10.2:8080/api/uploadsImages/}")
    private String uploadUrlPrefix;

    // 允许的文件类型
    private static final String[] ALLOWED_EXTENSIONS = {
            ".jpg", ".jpeg", ".png", ".gif", ".bmp"
    };

    // 最大文件大小 (10MB)
    private static final long MAX_FILE_SIZE = 10 * 1024 * 1024;

    /**
     * 存储上传的文件（按用户ID分目录存储）
     *
     * @param file   上传的文件
     * @param userId 用户ID（学号）
     * @return 文件的访问URL
     * @throws IOException 如果存储过程中发生错误
     */
    public String storeFile(MultipartFile file, String userId) throws IOException {
        // 验证文件类型和大小
        validateFile(file);

        // 生成唯一文件名
        String fileName = generateUniqueFileName(file.getOriginalFilename());

        // 创建用户ID对应的目录
        Path userDir = Paths.get(uploadRootPath, userId);
        if (!Files.exists(userDir)) {
            Files.createDirectories(userDir);
        }

        // 创建存储路径
        Path targetLocation = userDir.resolve(fileName);

        // 保存文件
        Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

        // 返回文件URL (使用相对路径)
        return uploadUrlPrefix + userId + "/" + fileName;
    }

    /**
     * 验证文件类型和大小
     *
     * @param file 上传的文件
     */
    private void validateFile(MultipartFile file) {
        // 检查文件是否为空
        if (file.isEmpty()) {
            throw new IllegalArgumentException("上传的文件为空");
        }

        // 检查文件大小
        if (file.getSize() > MAX_FILE_SIZE) {
            throw new IllegalArgumentException("文件大小超过限制 (10MB)");
        }

        // 检查文件类型
        String fileName = file.getOriginalFilename();
        if (fileName != null && fileName.contains(".")) {
            String extension = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
            boolean isValidExtension = false;

            for (String allowedExt : ALLOWED_EXTENSIONS) {
                if (allowedExt.equals(extension)) {
                    isValidExtension = true;
                    break;
                }
            }

            if (!isValidExtension) {
                throw new IllegalArgumentException("不支持的文件类型，只允许上传图片文件");
            }
        } else {
            throw new IllegalArgumentException("无法识别文件类型");
        }
    }

    /**
     * 生成唯一文件名
     *
     * @param originalFileName 原始文件名
     * @return 唯一文件名
     */
    private String generateUniqueFileName(String originalFileName) {
        // 如果原始文件名为空，则直接生成一个UUID作为文件名
        if (originalFileName == null || originalFileName.isEmpty()) {
            return UUID.randomUUID().toString();
        }

        // 初始化文件扩展名变量
        String extension = "";
        // 查找文件名中的最后一个点，用于获取文件扩展名
        int extIndex = originalFileName.lastIndexOf(".");
        // 如果找到了扩展名，则将其保存到extension变量中
        if (extIndex > 0) {
            extension = originalFileName.substring(extIndex);
        }

        // 使用UUID生成唯一文件名，并保留原始文件的扩展名
        return UUID.randomUUID().toString() + extension;
    }

    /**
     * 删除文件
     *
     * @param filePath 文件相对路径
     * @return 删除成功返回true，否则返回false
     */
    public boolean deleteFile(String filePath) {
        // 检查文件路径是否为空
        if (filePath == null || filePath.isEmpty()) {
            return false;
        }

        try {
            // 安全处理：只允许删除uploadRootPath目录下的文件
            Path uploadDir = Paths.get(uploadRootPath).normalize();
            Path fileToDelete = uploadDir.resolve(filePath).normalize();

            // 确保文件路径在允许的目录下，防止路径遍历攻击
            if (!fileToDelete.startsWith(uploadDir)) {
                throw new IllegalArgumentException("不安全的文件路径");
            }

            // 尝试删除文件，如果文件存在则返回true，否则返回false
            return Files.deleteIfExists(fileToDelete);
        } catch (IOException e) {
            // 异常处理：打印错误信息并返回false
            System.err.println("删除文件失败: " + e.getMessage());
            return false;
        }
    }
}